package com.thoughtworks;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class ThoughtWorksUtil {

	// 记录是否已经报废或者报废提醒
	// 0 表示已经报废
	// 1 表示报废提醒
	private static int writeOffFlag = 0;

	// 报废
	private static List<Car> writeOffs = new ArrayList<Car>();
	// 每一万公里保养
	private static List<Car> distanceRelateds = new ArrayList<Car>();
	// 定期保养
	private static List<Car> timeRelateds = new ArrayList<Car>();
	// 当前日期
	private static Date submitDate = null;

	/**
	 * 获取输入的数据
	 * 
	 * @return 返回封装完成的数据集合
	 * @throws Exception
	 */
	public static List<Car> getInputData() throws Exception {
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("SubmitDate: ");
		Scanner scanner = new Scanner(System.in);
		String dateStr = scanner.next();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
		submitDate = simpleDateFormat.parse(dateStr);
		String s;
		List<Car> cars = new ArrayList<Car>();
		while (true) {
			s = bufferedReader.readLine();
			if (s.length() != 0) {
				String[] split = s.split("\\|");
				Car car = null;
				for (int i = 0; i < split.length; i++) {
					car = new Car();
					car.setNumber(split[0]);
					car.setPurchaseDate(simpleDateFormat.parse(split[1]));
					car.setBrandName(split[2]);
					car.setCurrentKilometers(Integer.parseInt(split[3]));
					car.setIsRepair(split[4]);
				}
				cars.add(car);
			} else {
				break;
			}
		}
		// 关闭流
		scanner.close();
		return cars;
	}

	public static void checkList(List<Car> cars) throws Exception {
		// 对获取到的数据集合进行遍历
		for (Car car : cars) {
			// 
			Map<String, Integer> df = check(car, submitDate);
			if (df.get("write_off") == 1) {
				writeOffs.add(car);
			}
			if (df.get("distance_related") == 1) {
				distanceRelateds.add(car);
			}
			if (df.get("time_related") == 1) {
				timeRelateds.add(car);
			}
		}
	}

	/**
	 * 显示结果
	 */
	public static void showResult() {
		System.out.println("Reminder\n==================\n\n");
		// 输出定期保养信息
		showTimeRelated(timeRelateds);
		// 输出每一万米保养信息
		showDistanceRelated(distanceRelateds);
		// 输出报废信息
		showWriteOff(writeOffs);
	}

	/**
	 * 判断车辆提醒类型
	 * 
	 * @param car
	 * @param submitDate
	 *            当前日期
	 * @return
	 * @throws Exception
	 */
	private static Map<String, Integer> check(Car car, Date submitDate) throws Exception {

		// 记录是否是提醒（报废提醒，没1万公里提醒，定期保养提醒）     一辆车对应一个map
		Map<String, Integer> result = new HashMap<String, Integer>();

		// 购车日期
		Date purchaseDate = car.getPurchaseDate();
		Calendar c = Calendar.getInstance();
		c.setTime(purchaseDate);
		// 当前日期
		Calendar par = Calendar.getInstance();
		par.setTime(submitDate);
		writeOffFlag = 0;

		// 公里数
		int currentKilometer = car.getCurrentKilometers();

		// 判断是否报废
		// 判断是否大修
		int flag;
		if ("T".equals(car.getIsRepair())) {
			// 大修
			c.add(Calendar.DATE, 1095);
		} else {
			// 无大修
			c.add(Calendar.DATE, 2190);
		}
		flag = is_Scrap(c, par);
		if (flag == 1) {
			result.put("write_off", 1);
		} else {
			result.put("write_off", 0);
		}

		// ===========================================================

		// 判断是否一万公里保养
		if (writeOffFlag == 1) {
			// 报废提醒或报废
			result.put("distance_related", 0);
		} else {
			int res = currentKilometer % 10000;
			if (res >= 9500 || res == 0) {
				result.put("distance_related", 1);
			} else {
				result.put("distance_related", 0);
			}
		}

		// ===========================================================
		// 重新初始化时间  
		c.setTime(purchaseDate);

		// 判断定期保养
		// 判断是否报废
		if (writeOffFlag == 0) {// 没报废
			// 判断是否大修
			if ("T".equals(car.getIsRepair())) {
				// 大修
				findRecentTime(c, par, 3);
			} else {
				// 无大修
				// 看年限
				int car_year = par.get(Calendar.YEAR) - c.get(Calendar.YEAR);
				if (car_year < 3) {
					// 3年以下   寻找未来的第一次保养日期
					findRecentTime(c, par, 12);
				} else {
					// 前三年按照12月一次保养   后面的按照6个月一次保养
					c.add(Calendar.YEAR, 3);
					findRecentTime(c, par, 6);
				}
			}
			// 判断是否在时间区间内，上个月的1号到保修日
			if (scrap_month(c).getTime() <= submitDate.getTime() && c.getTime().getTime() >= submitDate.getTime()) {
				// 这个车满足定期保养
				if (result.get("distance_related") == 1) {
					// 这个车满足每1万公里保养
					
					// 定期保养和每1万公里都满足时，按照每1万公里保养计
					result.put("time_related", 0);
				} else {
					// 满足定期保养，不满足每一万公里保养
					result.put("time_related", 1);
				}
			} else {
				// 不满足定期保养
				result.put("time_related", 0);
			}
		} else {
			// 已报废
			result.put("time_related", 0);
		}
		return result;
	}

	// 是否提醒
	private static int is_Scrap(Calendar c, Calendar submitDate) throws Exception {

		if (scrap_month(c).getTime() <= submitDate.getTime().getTime()
				&& submitDate.getTime().getTime() < c.getTime().getTime()) {
			// 报废
			writeOffFlag = 1;
			
			// 提醒
			return 1;
		} else {
			if (submitDate.getTime().getTime() >= c.getTime().getTime()) {
				// 报废
				writeOffFlag = 1;
			} else {
				// 不报废
				writeOffFlag = 0;
			}
			// 不提醒
			return 0;
		}
	}

	// 车辆报废时，从上一个月就开始提醒
	private static Date scrap_month(Calendar c) throws Exception {
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		int day = 1;
		if (month == 1) {// 如果月份时1月
			year = c.get(Calendar.YEAR) - 1; // 报废应该是上一年的12月份
			month = 12;
		} else {
			month = month - 1;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.parse(year + "-" + month + "-" + day);

	}

	/**
	 * 寻找par（当前日期）后面的第一次保养日
	 * @param c
	 *            购车日期
	 * @param par
	 *            当前日期
	 * @param interval
	 *            月份时间间隔
	 */
	private static void findRecentTime(Calendar c, Calendar par, int interval) {
		while (c.getTime().getTime() < par.getTime().getTime()) {
			c.add(Calendar.MONTH, interval);
		}
	}

	/**
	 * 信息输出
	 * 
	 * @param list
	 */
	public static void print(List<Car> list) {
		// 自定义排序
		Collections.sort(list, new Comparator<Car>() {
			@Override
			public int compare(Car o1, Car o2) {
				return o1.getBrandName().compareTo(o2.getBrandName());
			}
		});
		for (int i = 0; i < list.size(); i++) {
			Car car0 = list.get(i);
			if (!car0.getIsRepeat()) {
				for (int j = i + 1; j < list.size(); j++) {
					Car car00 = list.get(j);
					if (car0.getBrandName().equals(car00.getBrandName())) {
						car00.setIsRepeat(true);// 重复了就设置重复，以后不在遍历
						car0.setRepeatCount(car0.getRepeatCount() + 1);// 重复的数量加1
						car0.setNumber(car0.getNumber() + "," + car00.getNumber());// 把当前的number合在一起，为了对应输出格式
					}
				}
				System.out.println(car0.getBrandName() + ": " + car0.getRepeatCount() + " (" + car0.getNumber() + ")");
			}
		}
	}

	/**
	 * 显示定期保养的记录
	 * 
	 * @param timeRelateds
	 *            定期保养的车辆集合
	 */
	public static void showTimeRelated(List<Car> timeRelateds) {
		System.out.println("* Time-related maintenance coming soon...");
		print(timeRelateds);
	}

	/**
	 * 显示每一万公里保养的记录
	 * 
	 * @param distanceRelateds
	 *            每一万公里保养的车辆集合
	 */
	public static void showDistanceRelated(List<Car> distanceRelateds) {
		System.out.println("\n\n* Distance-related maintenance coming soon...");
		print(distanceRelateds);

	}

	/**
	 * 显示报废的记录
	 * 
	 * @param writeOffs
	 *            报废的车辆集合
	 */
	public static void showWriteOff(List<Car> writeOffs) {
		System.out.println("\n\n* Write-off coming soon...");
		print(writeOffs);
	}

}
